package com.pcbly.web.components.utils.security;
/**
 * A utility class for encoding a binary MD5 digest as a string.
 */
public class MD5Encoder {

  private static final char[] _hexadecimal =
    {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
     'a', 'b', 'c', 'd', 'e', 'f'};

  private static java.security.MessageDigest _digest;

  /**
   * Creates a new instance of MD5Encoder.
   */
  public MD5Encoder() {
  }


  /**
   * Encodes the 128 bit (16 bytes) MD5 into a 32 character String.
   *
   * @param binaryData The byte array containing the digest.
   *
   * @return the encoded MD5.
   *
   * @throws java.lang.NullPointerException if the given binary data is null
   * @throws java.lang.IllegalArgumentException if the given binary data is not
   *                                            16 bytes in length.
   */
  public static String encode(byte[] binaryData) {

    if (binaryData.length != 16) {
      throw new java.lang.IllegalArgumentException();
    }

    char[] buffer = new char[32];

    for (int i=0; i < 16; i++) {
      int low = (int) (binaryData[i] & 0x0f);
      int high = (int) ((binaryData[i] & 0xf0) >> 4);
      buffer[i*2] = _hexadecimal[high];
      buffer[i*2 + 1] = _hexadecimal[low];
    }

    return new String(buffer);
  }

  /**
   * Produce an MD5 digest the given byte array.
   *
   * @param binaryData The bytes to be digested.
   *
   * @return the digest as a 128 bit (16 bytes) MD5.
   *
   * @throws java.lang.NullPointerException if the given binary data is null.
   *
   * @see java.security.MessageDigest
   */
  public static byte[] digest(byte[] binaryData) {
    if (_digest == null) {
      synchronized (MD5Encoder.class) {
        if (_digest == null) {
          try {
            _digest = java.security.MessageDigest.getInstance("MD5");
          } catch (java.security.NoSuchAlgorithmException nsae) {
            throw new java.lang.IllegalStateException(nsae.getClass().getName()+": "+nsae.getMessage());
          }
        }
      }
    }
    return _digest.digest(binaryData);
  }

}
